import { useState, useRef, useEffect, useCallback, useContext } from "react";

import InfiniteViewer from "react-infinite-viewer";
import Selecto from "react-selecto";
import { GroupManager } from "@moveable/helper";
import { deepFlat } from "@daybrush/utils";

import ViewContainer from "./container";
import { EditorGlobalContext } from "../../consts";

export default function CanvasIndex() {
	const infiniteViewer = useRef(null);
	const selectoRef = useRef(null);

	const moveableRef = useRef(null);
	const [moveableTargets, setMoveableTargets] = useState([]);
	const groupManagerRef = useRef();

	const { editorPageInfo } = useContext(EditorGlobalContext);
	useEffect(() => {
		const elements = selectoRef.current.getSelectableElements();
		groupManagerRef.current = new GroupManager([], elements);
	}, [editorPageInfo]);

	const setSelectedTargets = useCallback(nextTargetes => {
		selectoRef.current.setSelectedTargets(deepFlat(nextTargetes));
		setMoveableTargets(nextTargetes);
	}, []);

	return (
		<>
			<div className="canvas-wrapper">
				<div className="canvas-container">
					<Selecto
						ref={selectoRef}
						dragContainer={infiniteViewer.current}
						selectableTargets={[".selecto-area .target"]}
						hitRate={0}
						selectByClick={true}
						selectFromInside={false}
						toggleContinueSelect={["shift"]}
						ratio={0}
						onDragStart={e => {
							const moveable = moveableRef.current;
							const target = e.inputEvent.target;
							const flatted = moveableTargets.flat(3);
							if (moveable.isMoveableElement(target) || flatted.some(t => t === target || t.contains(target))) {
								e.stop();
							}
						}}
						onSelectEnd={e => {
							const { isDragStart, isClick, added, removed, inputEvent } = e;
							const moveable = moveableRef.current;

							if (isDragStart) {
								inputEvent.preventDefault();
								moveable.waitToChangeTarget().then(() => {
									moveable.dragStart(inputEvent);
								});
							}

							const groupManager = groupManagerRef.current;
							// console.log(groupManager);
							let nextChilds;
							if (isDragStart || isClick) {
								nextChilds = groupManager.selectSingleChilds(moveableTargets, added, removed);
							} else {
								nextChilds = groupManager.selectSameDepthChilds(moveableTargets, added, removed);
							}

							e.currentTarget.setSelectedTargets(nextChilds.flatten());

							setMoveableTargets(nextChilds.targets());
						}}></Selecto>
					<InfiniteViewer
						className="infinite-viewer"
						ref={infiniteViewer}
						useAutoZoom={true}
						useTransform={false}
						useWheelScroll={true}
						useForceWheel={true}
						mouseDragKeyModifier={"ctrl"}
						pinchThreshold={50}
						maxPinchWheel={3}>
						<ViewContainer
							moveableRef={moveableRef}
							moveableTargets={moveableTargets}
							groupManagerRef={groupManagerRef}
							selectoRef={selectoRef}
							setSelectedTargets={setSelectedTargets}></ViewContainer>
					</InfiniteViewer>
				</div>
			</div>
			<style global jsx>{`
				.canvas-wrapper {
					width: 100%;
					height: 100%;
					background: #ebeced;
				}

				.canvas-container {
					width: 100%;
					height: 100%;
					background: #00000012;
					box-shadow: 0 0 15px #00000012;
				}

				.canvas-container .infinite-viewer {
					width: 100%;
					height: 100%;
				}

				.canvas-container .infinite-viewer .infinite-viewer-scroll-thumb {
					background: #bfbfbf;
				}

				.selecto-selection {
					position: fixed;
					display: none;
					border: 1px solid #4af;
					background: rgba(68, 170, 255, 0.5);
					pointer-events: none;
					will-change: transform;
					z-index: 99;
				}
			`}</style>
		</>
	);
}
